/**
  ******************************************************************************
  * File Name          : ctrl_vfd.c
  * Description        : Code for data process applications
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */
#include "ctrl_common.h"

#if (VFD_VER == 710)
/* Includes ------------------------------------------------------------------*/
#include "tskcfg.h"
#include "bsp.h"
#include "collector.h"
#include "spiflash.h"

extern void VFD_BspInit(void);
extern void VFD_Rs485Send(const uint8_t *buf, uint32_t len);

TaskHandle_t xCtrVfd_Thd = NULL;
StaticTask_t xCtrVfd_Tcb;
StackType_t  xCtrVfd_Stk[ CTRVFD_STACK_SIZE ];

QueueHandle_t  CtrVfd_QMsg_qhd;
static StaticQueue_t ctrvfd_qmsg_stru;
static uint8_t       ctrvfd_qmsg_area[ CTRVFD_QMSG_LENGTH * CTRVFD_QMSG_ITEMSIZE ];

static uint16_t crc16(uint8_t* data_in, uint32_t length)
{
	uint16_t crc;
	uint16_t i;
	
	crc=0xFFFF;
	
	while(length-- != 0)
	{
		crc=(crc ^ ((*data_in)&0xff))&0xffff;
		
		for(i=0; i<8; i++)
		{
			if((crc & 0x0001)!=0)
			{
				crc=((crc)>>1);
				crc=((crc) ^ 0xA001);
			}
			else
			{
				crc=((crc)>>1);
			}
		}
		
		data_in++;
	}
	
	return(crc&0xffff);
}

static void vfd_cmd_stop(uint8_t vfd_id)
{
	uint8_t buf[12];
	uint16_t crc = 0;
	
	buf[0] = vfd_id;
	buf[1] = 0x06;
	buf[2] = 0x20;
	buf[3] = 0x00;
	buf[4] = 0x00;
	buf[5] = 0x04;
	
	crc = crc16(buf, 6);
	buf[6] = crc & 0xFF;
	buf[7] = crc >> 8;
	
	VFD_Rs485Send(buf, 8);
}

static void vfd_cmd_start(uint8_t vfd_id, uint8_t hz)
{
	uint8_t buf[16];
	uint16_t crc = 0;
	
	buf[0] = vfd_id;
	buf[1] = 0x10;
	buf[2] = 0x20;
	buf[3] = 0x00;
	buf[4] = 0x00;
	buf[5] = 0x02;
	buf[6] = 0x04;
	buf[7] = 0x00;
	buf[8] = 0x01;
	buf[9] = (hz*100)>>8; 
	buf[10] = (hz*100)&0xFF;  //频率低字节
	
	crc = crc16(buf, 11);
	buf[11] = crc & 0xFF;
	buf[12] = crc >> 8;
	
	VFD_Rs485Send(buf, 13);
}

void CtrVfd_Actuator(volatile uint8_t act, uint8_t ch, uint8_t mu)
{
	CtrVfd_QmsgType vfdmsg;
	
	if(Ctrl_ParaTD.vftd[ch] == 0)
	{
		/* 通道未使能,不执行任何动作 */
		Ctrl_StateVF.vfst[ch] = 'n';
		Ctrl_StateVF.vfjs[ch] = 0;
		return;
	}
	
	if(CtrVfd_QMsg_qhd == NULL)
	{
		return;
	}
	
	if(ch >= CTR_VFD_CHANNEL_ALLNUM)
  {
    return;
  }
	
	if((mu != 0)&&(Ctrl_ParaMD.mode != CTRL_MODE_MU))
	{
		return;
	}
	
	if((mu != 0)&&(Ctrl_ParaMD.mode == CTRL_MODE_MU))
	{
		if(act != 0)
		{
			Ctrl_StateVF.vfst[ch] = 'M';
			Ctrl_StateVF.vfjs[ch] = act;
		}
		else
		{
			Ctrl_StateVF.vfst[ch] = 'm';
			Ctrl_StateVF.vfjs[ch] = act;
		}
	}
	
	vfdmsg.vfdid = ch+1;
	vfdmsg.level = act;
	
	xQueueSend(CtrVfd_QMsg_qhd, &vfdmsg, 0);
}

void vCtrVfd_Task( void * pvParameters )
{
	CtrVfd_QmsgType vfdmsg;
	
	VFD_BspInit();
	
	CtrVfd_QMsg_qhd = xQueueCreateStatic(CTRVFD_QMSG_LENGTH, \
	                                     CTRVFD_QMSG_ITEMSIZE, \
	                                     ctrvfd_qmsg_area, \
	                                     &ctrvfd_qmsg_stru);
	
	while(1)
	{
		if(xQueueReceive(CtrVfd_QMsg_qhd, &vfdmsg, portMAX_DELAY) == pdTRUE)
		{
			if(vfdmsg.vfdid <= CTR_VFD_CHANNEL_ALLNUM)
			{
				if(vfdmsg.level <= 10)
				{
					if(vfdmsg.level == 0)
					{
						vfd_cmd_start(vfdmsg.vfdid, 0);
						vTaskDelay(100);
						vfd_cmd_stop(vfdmsg.vfdid);
					}
					else
					{
						vfd_cmd_start(vfdmsg.vfdid, (vfdmsg.level*4)+10);
					}
				}
			}
			
			vTaskDelay(100);
		}
	}
}
#endif
